﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Weazel.Willows.Model
{
	public class WaitTransition : Transition
	{
		protected List<string> waitList;
		public List<string> WaitList
		{
			get { return waitList; }
		}

		public WaitTransition()
		{
			this.waitList = new List<string>();
		}

		public Weazel.Gezel.Model.Expression GetWaitConditionExpression(Module module)
		{
			System.Diagnostics.Debug.Assert(waitList.Count > 0);

			Queue<Weazel.Gezel.Model.Expression> expressions =
				new Queue<Weazel.Gezel.Model.Expression>();

			foreach (string queue in waitList)
			{
				// find the reader
				ChannelReaderInterface @interface = null;

				foreach (ChannelReaderInterface reader in module.Readers.Values)
				{
					if (reader.LocalName == queue)
						@interface = reader;
				}

				//datapath.FindChannelReaderInterface(queue);

				if (@interface is QueueReaderInterface)
				{
					QueueReaderInterface queueReaderInterface =
						@interface as QueueReaderInterface;

					Weazel.Gezel.Model.LeafExpression leaf =
						new Weazel.Gezel.Model.LeafExpression(
							Weazel.Gezel.Model.ExpressionType.Identifier,
							queueReaderInterface.CanReadRegisterName
						);

					Weazel.Gezel.Model.UnaryExpression notExpr =
						new Weazel.Gezel.Model.UnaryExpression(
							Weazel.Gezel.Model.ExpressionType.Not,
							leaf
						);

					expressions.Enqueue(notExpr);
				}
				else if(@interface == null)
				{
					string message =
						string.Format("Identifier '{0}' in wait list not found not found in list of queues.", queue);

					throw new NullReferenceException(message);
				}
				else
				{
					string message =
						string.Format("Identifier '{0}' in wait list is not the name of a Queue (type: {1})", 
						queue,
						@interface.GetType().Name
					);

					throw new NotSupportedException(message);
				}
			}

			Weazel.Gezel.Model.Expression expr = expressions.Dequeue();
			while (expressions.Count > 0)
			{
				expr = new Weazel.Gezel.Model.BinaryExpression(
					Weazel.Gezel.Model.ExpressionType.Ior,
					expr,
					expressions.Dequeue()
				);
			}

			return expr;
		}
	}
}
